unit SmallStruct.View.TSSViewFactory;

interface

uses SmallStruct.Core.TSSObjectFactory,
  SmallStruct.View,
  SmallStruct.View.TSSView,
  SmallStruct.Core;

type
  TSSViewFactory = class(TSSObjectFactory, ISSViewFactory)
  protected
    function GetViewConfiguration(const AViewName: string): ISSConfiguration;
  private
    procedure InitModel(AView: ISSView);
    procedure InitInnerView(AView: ISSView);
  public
    function GetView(const AViewName: string): ISSView;
    procedure FreeView(AView: ISSView);
  end;

implementation

uses
  SmallStruct.Configuration,
  SmallStruct.Model,
  SmallStruct.Model.TSSModel;

{ TSSViewFactory }

procedure TSSViewFactory.FreeView(AView: ISSView);
var
  Model: ISSModel;
begin
  while AView.GetModelContainer.GetCount > 0 do
  begin
    Model := AView.GetModelContainer.GetObject(0) as TSSModel;
    AView.GetModelContainer.RemoveObject(0);
    ((GetSystemObject.GetGlobalObjectTable as ISSObjectContainer).GetObject(SS_MODEL_FACTORY_NAME) as ISSModelFactory).FreeModel(Model);
  end;

  AView.ReleaseObjectInstance;
end;

function TSSViewFactory.GetView(const AViewName: string): ISSView;
var
  ViewClass: TSSViewClass;
  ViewContext: TSSViewContext;
begin
  ViewClass := TSSViewClass(QueryClass(AViewName));
  Result := ViewClass.Create(nil);
  ViewContext := TSSViewContext.Create(nil);
  ViewContext.SetConfiguration(GetViewConfiguration(AViewName));
  Result.SetContext(ViewContext);

  if (ViewContext.GetConfiguration as ISSViewConfiguration).GetModelName.Count > 0 then
    InitModel(Result);

  Result.InitObject;

  if (ViewContext.GetConfiguration as ISSViewConfiguration).GetType = ssvtMultiView then
    InitInnerView(Result);
end;

function TSSViewFactory.GetViewConfiguration(const AViewName: string): ISSConfiguration;
begin
  Result := (GetSystemObject.GetConfigurationTable as ISSConfigurationTable).QueryViewConfiguration(AViewName);
end;

procedure TSSViewFactory.InitInnerView(AView: ISSView);
var
  Index: Integer;
  View: ISSView;
begin
  with (AView.GetContext.GetConfiguration as ISSViewConfiguration).GetInnerViewName do
    for Index := 0 to Count - 1 do
    begin
      View := GetView((AView.GetContext.GetConfiguration as ISSViewConfiguration).GetInnerViewName.Strings[Index]);
      (AView as ISSMultiView).GetViewContainer.AppendObject((AView.GetContext.GetConfiguration as ISSViewConfiguration).GetInnerViewName.Strings[Index], View.GetObjectInstance);
    end;
end;

procedure TSSViewFactory.InitModel(AView: ISSView);
var
  Index: Integer;
begin
  with (AView.GetContext.GetConfiguration as ISSViewConfiguration).GetModelName do
    for Index := 0 to Count - 1 do
      AView.GetModelContainer.AppendObject(Strings[Index], ((GetSystemObject.GetGlobalObjectTable as ISSObjectContainer).GetObject(SS_MODEL_FACTORY_NAME) as ISSModelFactory).GetModel(Strings[Index]).GetObjectInstance);
end;

end.
